package com.jt.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import com.jt.vo.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.UUID;

@Service
public class UserServiceImpl implements UserService{
   @Autowired
  private UserMapper mapper;

    @Override
    //h获取全部的用户数据展现在网页端
    public List<User> findAll() {
        return mapper.selectList(null);
    }



    /*根据用户 和密码尽心判断是否有效
        1.将明文进行加密处理 md5加密/md5Hash/sha1
        2.根据加密后的数据查询数据库
        3.
    * */
    @Override
    public String login(User user) {
      //1.获取原始密码
      String password=user.getPassword();
      //2.将密码进行加密
        //将传经来的数据进行加密DigestUtils.md5DigestAsHex() 返回一个字符串
      String md5= DigestUtils.md5DigestAsHex(password.getBytes());

       //3将加密后的密文给数据库设置
         user.setPassword(md5);
         //4将对象直接传，根据不为空的数据当做where条件
        QueryWrapper<User> queryWrapper=new QueryWrapper(user);
        //5.定义token不能重复 uuid：是有一个随机字符串 3.4*10的38次方 hash（时间戳加随机数）
         User userDb=mapper.selectOne(queryWrapper);
           String uuid= UUID.randomUUID().
              toString().replace("-", "");

               //三目运算 如果查询数据成功，返回我们的uuid的值
             return (userDb)==null?null:uuid ;
    }

    /*
    实现动态的查询，如果有数据就查询数据，没有就全部查
    利用mp的分页实现查询
    API 说明 selectPage（arg1,arg2）
       arg1 mp中的分页对象
       arg2 mp的分页构造器

    *
    * */
    @Override
    public PageResult getUserList(PageResult pageResult) {
      //1.定义mp的分页对象//（"分页的页数"，"分页的条数"）
        IPage iPage=new Page(pageResult.getPageNum(),pageResult.getPageSize());
      //2.构建条件查询构造器
        QueryWrapper queryWrapper=new QueryWrapper();

        //3.判断用户是否有输入数据 有效true
          boolean flag= StringUtils.hasLength(pageResult.getQuery());

            queryWrapper.like(flag, "username", pageResult.getQuery());
          //经过mp分页查询的将所有的数据封装到iPage对象中

           iPage=  mapper.selectPage(iPage, queryWrapper);
        //从分页对象中获得总记录数

        long total=iPage.getTotal();

        //获得分页结果
         List<User> rows=iPage.getRecords();

        return pageResult.setTotal(total).setRows(rows);
    }

    @Override
    @Transactional
    public void updateStatus(User user) {
        //根据对象中不为空的属性当做set条件 id作为where条件
       mapper.updateById(user);


    }

    @Override
    @Transactional
    public void addUser(User user) {
        String password=DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
         user.setPassword(password).setStatus(true);
        mapper.insert(user);
    }

    @Override
    public User selectId(Integer id) {

        return mapper.selectById(id);

    }

    @Override
    @Transactional
    public void updateUser(User user) {
          String password=DigestUtils.md5DigestAsHex(user.getPassword().getBytes());

          user.setPassword(password);
        mapper.updateById(user);

    }
/*
* aop：在不影响源码的条件下。对方法进行扩展
*  aop的通知类型：1.before 2.afterReturning 3.AfterThrowing
*               4.After 5.Around
*   前四个做数据的监控   注意用Around方法
* */


    /* @Transactional
    *     对应aop的Around 通知。实现对事务的控制
    *     spring默认的事务策略，
    * 1.如果控制的方法运行时异常。事务回滚。
    * 2.如果控制的方法。检查异常（编译异常），事务不回滚，sping默认让程序员自己处理异常
    *
    * 这个注解有两个属性
    *@Transactional( rollbackFor=Exception.class )表示遇到什么的
    * 样的异常事务回滚
    * */
    @Override
    @Transactional//针对数据库中的事务控制。开发的注解
    public void deleteById(Integer id) {
        mapper.deleteById(id);
       /*
        int a=1/0;
       *定义报错检查信息。运行时后台出错。前台收到失败提示
       *
       * */
    }

   /*
    //直接使用sql写的数据库操作，没有实现动态查询
    @Override
    public PageResult getUserList(PageResult pageResult) {
          *//*mysql的分页查询
          select *from user limit 0,1；
          *    n是页数/m是条数
          分页的语法：select *from user limit (n-1)m,m；
          * *//*
          //1.获取总记录数
        long total=mapper.selectCount(null);
        //2.获取分页后的结果
        int startIndex= (pageResult.getPageNum()-1)*pageResult.getPageSize();
        List<User> rows=mapper.getUserList(startIndex,pageResult.getPageSize());
        return pageResult.setTotal(total).setRows(rows);

    }*/
}
